/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gridworld_v5;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;

/**
 *
 * @author Jonah
 */
public class Tile extends JButton implements ActionListener {
    /*implementation comment*/
    ////<editor-fold defaultstate="collapsed" desc="Instanced Variables">
    private PossibleStates tileState;
    private Integer neighborsIndex[] = new Integer[9];
    //think of this as a 3x3 grid with the center tile (tile[4]) representing 
    private ArrayList<Tile> neighbors = new ArrayList();
    //This is a list of the actual neighboring tiles, whereas neighbors Index is
    //only the potential indices of neighboring tiles.
    private ArrayList<ThreadedActor> occupants = new ArrayList();
    private GWimages icons;
    private Game game;
    private Board board;
    //this tile
    //</editor-fold>
    ////<editor-fold defaultstate="collapsed" desc="Constructor">
    public Tile(Integer index, Game game, Board board, GWimages icons) {
        //neighborsIndex[4] = index;
        this.game = game;
        this.icons = icons;
        this.board = board;
        tileState = PossibleStates.Empty;
        
        addActionListener(this);
        generateNeighborsIndex(index);
        //generateNeighbors();
    }
    //</editor-fold>
    ////<editor-fold defaultstate="collapsed" desc="Class Methods">
    public Integer getIndex(){
        return neighborsIndex[4];
    }
    private void generateNeighborsIndex( Integer currentIndex ){
        neighborsIndex[0] = ( currentIndex - board.getColumns() ) - 1;
        neighborsIndex[1] = neighborsIndex[0] + 1;
        neighborsIndex[2] = neighborsIndex[1] + 1;
        neighborsIndex[3] = currentIndex - 1;
        neighborsIndex[4] = currentIndex;
        neighborsIndex[5] = currentIndex + 1;
        neighborsIndex[6] = ( currentIndex + board.getColumns() ) - 1;
        neighborsIndex[7] = neighborsIndex[6] + 1;
        neighborsIndex[8] = neighborsIndex[7] + 1;
        
        if (currentIndex < board.getColumns()){
            neighborsIndex[0] = null;
            neighborsIndex[1] = null;
            neighborsIndex[2] = null;
        }
        if (currentIndex > ((board.getColumns()*board.getRows())-board.getColumns())){
            neighborsIndex[6] = null;
            neighborsIndex[7] = null;
            neighborsIndex[8] = null;
        }
        if ((currentIndex % board.getColumns() )== 0) {
            neighborsIndex[0] = null;
            neighborsIndex[3] = null;
            neighborsIndex[6] = null;
        }
        if ((currentIndex % board.getColumns() ) == (board.getColumns()-1) ) {
            neighborsIndex[2] = null;
            neighborsIndex[5] = null;
            neighborsIndex[8] = null;
        }
    }
    public void update(){
        tileState = getTileState();
        switch(tileState){
            case Bug:
                setIcon(icons.bugIcon);
                break;
            case Critter:
                setIcon(icons.critterIcon);
                break;
            case Flower:
                setIcon(icons.flowerIcon);
                break;
            case Rock:
                setIcon(icons.rockIcon);
                break;
            case Bug_Rock:
                setIcon(icons.bugRockIcon);
                break;
            case Bug_Flower:
                setIcon(icons.bugFlowerIcon);
                break;
            case Empty:
            default:
                setIcon(null);
        }
    }
    public void addActor( ThreadedActor ta){
        occupants.add(ta);
        update();
    }
    public void removeActor( ThreadedActor ta) { 
        occupants.remove(ta);
    }
    public PossibleStates getTileState(){
        
        if ( tileState.equals(PossibleStates.Invalid)) {
            return tileState;
        }
        
        boolean isBug = false, isFlower = false, isRock = false, isCritter = false;

        for ( ThreadedActor a : occupants){
            if (a.getActorType().equals(PossibleStates.Bug)){
                isBug = true;
            }
            if (a.getActorType().equals(PossibleStates.Flower)){
                isFlower = true;
            }
            if (a.getActorType().equals(PossibleStates.Rock)){
                isRock = true;
            }
            if (a.getActorType().equals(PossibleStates.Critter)){
                isCritter = true;
            }
        }
        //returns
        if ( isBug && isFlower){
            return PossibleStates.Bug_Flower;
        }else if ( isBug && isRock ){
            return PossibleStates.Bug_Rock;
        }else if (isCritter){
            return PossibleStates.Critter;
        }else if (isBug){
            return PossibleStates.Bug;
        }else if (isRock){
            return PossibleStates.Rock;
        }else if (isFlower){
            return PossibleStates.Flower;
        }else
            return PossibleStates.Empty;
    }
    public void generateNeighbors(){
        //System.out.println("generateNeighbors()");
        neighbors.clear();
        for ( Integer i: neighborsIndex){
            //System.out.print(i);
            if (i != null){
                try{
                    if ( !(board.getTile(i).getTileState().equals(PossibleStates.Invalid)) ) {
                        //System.out.println("added neighbor");
                        neighbors.add(board.getTile(i));
                    }
                } catch (ArrayIndexOutOfBoundsException e){
                }
            }
        }
    }
    public ArrayList<ThreadedActor> getOccupants() {
        return occupants;
    }
    public List getNeighbors(){
        return neighbors;
    }
    //</editor-fold>
    ////<editor-fold defaultstate="collapsed" desc="Interface Override Methods">
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println( toString() );
        //System.err.println("Tile.actionPerformed still needs to be implemented");
        game.processTileClicked(this);
    }
    //</editor-fold>

    @Override
    public String toString() {
        //StringBuffer neighbors = "neighborsIndex=" + neighborsIndex ;
        StringBuffer neighborsIndex = new StringBuffer ("neighborsIndex= ");
        for ( Integer i : this.neighborsIndex ){
            neighborsIndex.append( (i + " ") );
        }
        StringBuffer neighbors = new StringBuffer ("neighbors= ");
        for (Tile t : this.neighbors){
            neighbors.append(t.getIndex() + " ");
        }
        return "Tile" + this.neighborsIndex[4] + "{" + neighbors +'}';
    }

    
}
